import 'package:flutter/material.dart';

///状态的动画列表Widget
class AnimatedListSample extends StatefulWidget {
  @override
  _AnimatedListSampleState createState() => _AnimatedListSampleState();
}

///动画列表Widget state
class _AnimatedListSampleState extends State<AnimatedListSample> {

  final GlobalKey<AnimatedListState> _listKey  = GlobalKey<AnimatedListState>();

  ListModel<int> _list;
  //选中的项
  int _selectedItem;

  //下一个项
  int _nextItem;

  //初始化状态
  @override
  void initState(){
    super.initState();
    _list = ListModel<int>(
      listKey: _listKey,
      initialItems: <int>[0,1,2],
      removedItemBuilder: _buildRemovedItem,
    );
    _nextItem = 3;
  }

  ///构建项目
  Widget _buildItem(BuildContext context,int index,Animation<double> animation) {
    return CardItem(
      animation: animation,
      item: _list[index],
      selected: _selectedItem == _list[index],
      onTap: () {
        setState(() {
          _selectedItem = _selectedItem == _list[index] ? null : _list[index];
        });
      },
    );
  }

  void _insert(){
    final int index = _selectedItem == null? _list.length:_list.indexOf(_selectedItem);
    _list.insert(index, _nextItem++);
  }

  void _remove(){
    if(_selectedItem != null){
      _list.removeAt(_list.indexOf(_selectedItem));
      setState(() {
        _selectedItem = null;
      });
    }
  }

  Widget _buildRemovedItem(int item,BuildContext context, Animation<double> animation){
    return CardItem(
      animation: animation,
        item: item,
        selected: false,
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const Text('AnimatedList'),
            actions: <Widget>[
              IconButton(
                icon: const Icon(Icons.add_circle),
                onPressed: _insert,
                tooltip: 'insert a new item',
              ),
              IconButton(
                icon: const Icon(Icons.remove_circle),
                onPressed: _remove,
                tooltip: 'remove the selected item',
              )
            ],
          ),
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: AnimatedList(itemBuilder: _buildItem,
              key: _listKey,
              initialItemCount: _list.length,),),
        )
    );
  }
}

class ListModel<E> {
  ListModel(
      {
        @required this.listKey,
        @required this.removedItemBuilder,
        Iterable<E> initialItems,}):
        assert(listKey != null),
        assert(removedItemBuilder != null),
        _items = List<E>.from(initialItems ?? <E>[]);

  final GlobalKey<AnimatedListState> listKey;

  final dynamic removedItemBuilder;

  final List<E> _items;

  AnimatedListState get _AnimatedListSampleState =>listKey.currentState;

  void insert(int index,E item){
    _items.insert(index, item);
    _AnimatedListSampleState.insertItem(index);
  }

  E removeAt(int index){
    final E removedItem = _items.removeAt(index);
    if(removedItem != null){
      _AnimatedListSampleState.removeItem(index,(BuildContext context,Animation<double> animation){
        return removedItemBuilder(removedItem,context,animation);
      });
    }
    return removedItem;
  }

  int get length => _items.length;

  /// ListModel[index]操作 重载 unary postfix 运算符重载
  E operator [](int index) => _items[index]; //todo 看dart 运算符重载

  int indexOf(E item) => _items.indexOf(item);

}

///卡片项
class CardItem extends StatelessWidget {
  final animation;
  final VoidCallback onTap;
  final int item;
  final bool selected;

  CardItem({
    Key key,
    @required this.animation,
    this.onTap,
    @required this.item,
    this.selected: false
  });

  @override
  Widget build(BuildContext context) {
    TextStyle textStyle = Theme
        .of(context)
        .textTheme
        .display1;

    if (selected) {
      textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
    }
    return Padding(
      padding: const EdgeInsets.all(2.0),
      child: SizeTransition(sizeFactor: animation, axis: Axis.vertical,
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: onTap,
          child: SizedBox(
            height: 128.0,
            child: Card(
              color: Colors.primaries[item % Colors.primaries.length],
              child: Center(
                child: Text('Item $item', style: textStyle,),
              ),
            ),
          ),
        ),),
    );
  }
}






